// Copyright (C) joyinter
// All rights reserved.
// 
// Author : Jiang Li
// Date   : 2005-1-4

#include "stdafx.h"
#include "cmd_handler.h"
#include "msvr_user.h"
#include "msvr_server.h"
#include "msvr_room.h"
#include "msvr_chat.h"

namespace JoyServer
{

// class CJoyCmdHandlerBase

CJoyCmdHandlerBase::CJoyCmdHandlerBase()
{
    enum
    {
        auth_admin = true,
        auth_user = false,
    };
#   define JOY_CMD_DEF(name, auth) \
    {\
        CHandlerInfo inf;\
		inf.m_pfnHandler = &JoyServer::CJoyCmdHandlerBase::handler_##name;\
        inf.m_admin = auth_##auth;\
        m_handlers[#name] = inf;\
    }
#   include "cmd_def.h"
}

CJoyCmdHandlerBase::~CJoyCmdHandlerBase()
{
}

// class CJoyCmdHandler

CJoyCmdHandler::CJoyCmdHandler()
{
    m_room  = NULL;

}

CJoyCmdHandler::~CJoyCmdHandler()
{
}

bool CJoyCmdHandler::Create(CJoyMainRoom* pRoom)
{
    m_room = pRoom;
    return true;
}

void CJoyCmdHandler::Destroy()
{
}

bool CJoyCmdHandler::ExtractParams(CCommandContext& context, CParamList& params)
{
    params.RemoveAll();
    PCSTR b = context.m_param;
    PCSTR e = b + context.m_param.GetLength();
    for(; b < e;)
    {
        b = strchr(b, '-');
        if(b == NULL)
        {
            break;
        }
        ++ b;
        PCSTR s = b;
        for(; b < e; ++ b)
        {
            if(*b == ' ' || *b == '\0' || *b == ':')
            {
                break;
            }
        }
        if(b == s)
        {
            context.m_user->SendMsg(m_room->m_roomChat->m_chatmsg_badCommand);
            return false;
        }
        CParamPair pp;
        pp.m_name.SetString(s, (int)(INT_PTR)(b-s));
        pp.m_name.Trim();
        if(*b != ':')
        {
            params.AddTail(pp);
            continue;
        }

        ++ b;
        s = b;
        for(; b < e; ++ b)
        {
            if(*b == ' ' || *b == '\0')
            {
                break;
            }
        }
        if(b == s)
        {
            context.m_user->SendMsg(m_room->m_roomChat->m_chatmsg_badCommand);
            return false;
        }
        pp.m_value.SetString(s, (int)(INT_PTR)(b-s));
        pp.m_value.Trim();
        params.AddTail(pp);
    }

    return true;
}

bool CJoyCmdHandler::ProcessCommand(CJoyMainUser* pUser, const JoyMessage::MC_Chat* msg)
{
    int len = msg->GetTextLength();
    if(len < 2)
    {
        return false;
    }
    PCSTR buf = msg->m_text;
    if(buf[0] != '/' || buf[1] != '/')
    {
        return false;
    }

    PCSTR cmdBegin  = buf+2;
    PCSTR cmdEnd    = cmdBegin;
    while(
        *cmdEnd != '\0' &&
        *cmdEnd != '\n' &&
        *cmdEnd != '\r' &&
        *cmdEnd != '\t' &&
        *cmdEnd != ' ' )
    {
        ++ cmdEnd;
    }
    if(cmdEnd == cmdBegin)
    {
        if(!pUser->IsAdminTroop())
        {
            return false;
        }
        pUser->SendMsg(m_room->m_roomChat->m_chatmsg_badCommand);
        return true;
    }

    CCommandContext context;

    CHandlerInfo inf;
    context.m_command.SetString(cmdBegin, (int)(INT_PTR)(cmdEnd-cmdBegin));
    if(!m_handlers.Lookup(context.m_command, inf))
    {
        if(!pUser->IsAdminTroop())
        {
            return false;
        }
        pUser->SendMsg(m_room->m_roomChat->m_chatmsg_badCommand);
        return true;
    }

    if(inf.m_admin)
    {
        if(!pUser->IsAdminTroop())
        {
            return false;
        }
    }
    context.m_user      = pUser;
    context.m_chatMsg   = msg;
    context.m_param     = cmdEnd;
    context.m_param.Trim();
    (this->*inf.m_pfnHandler)(context);

    return true;
}

} // namespace JoyServer